<div id="app"></div>

<style>
    #app{
        text-align: center;
        font-size: 60px;
    }
    .red{
        color: red;
    }
    .green{
        color: green;
    }
</style>
<script>
    const h = (tag, props, children) => {
        return {
            tag,
            props,
            children
        }
    }
    const mount = (vnode, container) => {
        console.log('mount')
        console.log(vnode)
        const el = vnode.el =  document.createElement(vnode.tag)
        // 处理props
        for (const key in vnode.props) {
            const value = vnode.props[key]
            el.setAttribute(key, value)

        }
        // 处理children
        if (vnode.children) {
            vnode.children.forEach(child => {
                if (typeof child === "string") {
                    el.append(child);
                } else if (typeof child === "object") {
                    //child是一个对象时,说明child是一个元素节点
                    //这时就要递归调用mount
                    mount(child, el);
                }
            })
        }


        container.appendChild(el)
    }
    const patch = (n1,n2) => {
        console.log(n1,n2)
        if(n1.tag === n2.tag) {
            let el = n2.el =  n1.el;
            const oldProps = n1.props || {}
            const newProps = n2.props || {}
            // 循环新的props 新旧值比较
            for (const key in newProps) {
                const oldValue = oldProps[key]
                const newValue = newProps[key]
                if(newValue !== oldValue) {
                    el.setAttribute(key, newValue)
                }
            }
            // 循环老的props 删除不存在的值
            for (const key in oldProps) {
                if(!(key in newProps)) {
                    el.removeAttribute(key)
                }
            }




            const oldChildren = n1.children
            const newChildren = n2.children
            if(typeof newChildren === 'string'){
                if(typeof oldChildren === 'string'){
                    if(oldChildren !== newChildren) {
                        el.textContent = newChildren;
                    }
                } else {
                    el.textContent = newChildren;
                }
            } else {
                if(typeof oldChildren === 'string'){
                    el.innerHTML = ''
                    newChildren.forEach(item => {
                        mount(item, el)
                    })
                } else {
                    const commonLength = Math.min(oldChildren.length, newChildren.length)
                    for (let i = 0; i < commonLength; i++) {
                        patch(oldChildren[i], newChildren[i])
                    }
                    if(newChildren.length > oldChildren.length) {
                        newChildren.splice(oldChildren.length).forEach(child => {
                            mount(child, el)
                        })
                    } else if(newChildren.length  < oldChildren.length) {
                        oldChildren.splice(newChildren.length).forEach(child =>  {
                            el.removeChild(child.el)
                        })
                    }
                }
            }
        } else {
            // todo 标签不一样
        }
    }
    const vdom = h('div', {class: 'red'}, [
        h('span', null, ['hello'])
    ])
    mount(vdom, document.getElementById('app'))
    const vdom2 = h('div', {class: 'green'}, [
        h('span', null, 'changed!')
    ])
    setTimeout(() => {
        patch(vdom, vdom2)
    }, 1000)
</script>